package com.spicesoft.cachedobjects;

import java.io.Serializable;
import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import com.danga.MemCached.MemCachedClient;
import com.google.protobuf.GeneratedMessage;

public class CachingInterceptor implements MethodInterceptor {

	private static MemCachedClient client = new MemCachedClient();

	public static class Entry implements Serializable {
		String type;
		byte[] data;
	}

	@Override
	public Object invoke(MethodInvocation method) throws Throwable {
		Object[] args = method.getArguments();
		String key = argsToKey(args);
		Entry cached = (Entry) client.get(key);
		if (cached != null) {
			Class<?> msgClass = Class.forName(cached.type, false,
					CachingInterceptor.class.getClassLoader());
			Method parser = msgClass.getMethod("parseFrom", byte[].class);
			return parser.invoke(cached.data);
		} else {
			GeneratedMessage value = (GeneratedMessage) method.proceed();
			Entry e = new Entry();
			e.type = value.getClass().getName();
			e.data = value.toByteArray();
			client.set(key, e);
			return value;
		}
	}

	private String argsToKey(Object[] args) {
		StringBuilder sb = new StringBuilder();

		for (Object arg : args) {
			sb.append(arg).append('_');
		}

		return sb.toString();
	}

}
